from typing import List, Optional
import os
from datetime import datetime, timedelta
from vnpy.trader.constant import Exchange
from ..datafeed.data_loader import PortfolioDataLoader

class StockCollection:
    """
    股票收藏管理器
    负责管理用户收藏的股票列表，提供添加、删除、加载和保存收藏列表的功能。
    """

    def __init__(self, data_loader: Optional[PortfolioDataLoader] = None):
        """
        构造函数
        :param data_loader: 数据加载器实例，用于获取股票价格和名称
        """
        self.collection: List[str] = []  # 用户收藏的股票代码列表
        self.data_loader = data_loader or PortfolioDataLoader()
        
        # 获取项目根目录
        current_dir = os.path.dirname(os.path.abspath(__file__))
        project_root = os.path.dirname(os.path.dirname(current_dir))
        
        # 设置收藏列表文件路径
        self.collection_file = os.path.join(project_root, "portfolio_trader/data", "collection.txt")
        
        # 确保 data 目录存在
        os.makedirs(os.path.dirname(self.collection_file), exist_ok=True)
        
        # 加载收藏列表
        self.load_collection()

    def add_to_collection(self, symbol: str) -> bool:
        """
        将股票代码添加到收藏列表
        :param symbol: 股票代码
        :return: 是否添加成功
        """
        if symbol not in self.collection:
            self.collection.append(symbol)
            self.save_collection()
            print(f"已将 {symbol} 添加到收藏列表")
            # 从datafeed中获取最近一年的股票数据
            start_date = datetime.now() - timedelta(days=365)
            end_date = datetime.now()
            bars = self.data_loader.load_daily_data(symbol, start_date, end_date)
            valuation = self.data_loader.load_valuation_data(symbol, start_date, end_date)
            return True
        return False

    def remove_from_collection(self, symbol: str) -> bool:
        """
        从收藏列表中移除股票代码
        :param symbol: 股票代码
        :return: 是否移除成功
        """
        if symbol in self.collection:
            self.collection.remove(symbol)
            self.save_collection()
            print(f"已将 {symbol} 从收藏列表中移除")
            return True
        return False

    def save_collection(self) -> None:
        """
        将收藏列表保存到文件
        """
        with open(self.collection_file, "w") as f:
            for symbol in self.collection:
                f.write(f"{symbol}\n")

    def load_collection(self) -> None:
        """
        从文件加载收藏列表
        """
        try:
            if os.path.exists(self.collection_file):
                with open(self.collection_file, "r") as f:
                    self.collection = [line.strip() for line in f.readlines()]
                print(f"已加载收藏列表，包含 {len(self.collection)} 只股票")
            else:
                print("收藏列表文件不存在，已创建空文件")
                self.save_collection()
        except Exception as e:
            print(f"加载收藏列表失败：{e}")
            self.collection = []

    def get_collection(self) -> List[str]:
        """
        获取收藏列表
        :return: 收藏的股票代码列表
        """
        return self.collection.copy()

    def get_stock_prices(self) -> dict:
        """
        获取收藏股票的最新价格
        :return: 股票代码和价格的字典
        """
        prices = {}
        current_time = datetime.now()
        
        for symbol in self.collection:
            try:
                # 获取最新价格数据
                bars = self.data_loader.load_daily_data(
                    symbol=symbol,
                    start_date=current_time - timedelta(days=5),
                    end_date=current_time
                )
                
                if bars and len(bars) > 0:
                    prices[symbol] = bars[-1].close_price
                else:
                    prices[symbol] = 0.0
            except Exception as e:
                print(f"获取{symbol}价格失败: {str(e)}")
                prices[symbol] = 0.0
                
        return prices

    def get_stock_names(self) -> dict:
        """
        获取收藏股票的名称
        :return: 股票代码和名称的字典
        """
        names = {}
        
        for symbol in self.collection:
            try:
                name = self.data_loader.get_stock_name(symbol)
                names[symbol] = name
            except Exception as e:
                print(f"获取{symbol}名称失败: {str(e)}")
                names[symbol] = ""
                
        return names

    def is_valid_symbol(self, symbol: str) -> bool:
        """
        验证股票代码是否有效
        :param symbol: 股票代码
        :return: 是否有效
        """
        import re
        pattern = r"^(600|601|603|688|000|002|300)\d{3}$"  # 匹配沪市/深市标准代码
        return bool(re.match(pattern, symbol))

    def get_exchange(self, symbol: str) -> Exchange:
        """
        根据股票代码获取交易所
        :param symbol: 股票代码
        :return: 交易所
        """
        if symbol.startswith(("600", "601", "603", "688")):
            return Exchange.SSE
        elif symbol.startswith(("000", "002", "300")):
            return Exchange.SZSE
        else:
            return Exchange.SSE  # 默认使用上交所